UNIX V6のnewproc()の実装
fork()の内部で呼ばれて、新しいプロセスを生成する関数
もっと詳しく書いてる
code:sys/ken/slp.c
newproc()
{
int a1, a2;
struct proc *p, *up;
register struct proc *rpp;
register *rip, n;
p = NULL;
retry:
この辺で新しいpidの決定
mpidはglobal変数でnewprocするたびにインクリメント
code:sys/ken/slp.c
mpid++;
if(mpid < 0) {
mpid = 0;
goto retry;
}
for(rpp = &proc0; rpp < &procNPROC; rpp++) { if(rpp->p_stat == NULL && p==NULL)
p = rpp;
if (rpp->p_pid==mpid)
goto retry;
}
if ((rpp = p)==NULL)
panic("no procs");
この辺で、親を子に複製している
code:sys/ken/slp.c
rip = u.u_procp;
up = rip;
rpp->p_stat = SRUN;
rpp->p_flag = SLOAD;
rpp->p_uid = rip->p_uid;
rpp->p_ttyp = rip->p_ttyp;
rpp->p_nice = rip->p_nice;
rpp->p_textp = rip->p_textp;
rpp->p_pid = mpid;
rpp->p_ppid = rip->p_pid;
rpp->p_time = 0;
code:sys/ken/slp.c
for(rip = &u.u_ofile0; rip < &u.u_ofileNOFILE;) if((rpp = *rip++) != NULL)
rpp->f_count++;
if((rpp=up->p_textp) != NULL) {
rpp->x_count++;
rpp->x_ccount++;
}
u.u_cdir->i_count++;
savu(u.u_rsav);
rpp = p;
u.u_procp = rpp;
rip = up;
n = rip->p_size;
a1 = rip->p_addr;
rpp->p_size = n;
code:sys/ken/slp.c
a2 = malloc(coremap, n);
if(a2 == NULL) { // mallocに失敗. スワップする
rip->p_stat = SIDL; // 親プロセスをidle状態に
rpp->p_addr = a1;
savu(u.u_ssav);
xswap(rpp, 0, 0);
rpp->p_flag =| SSWAP;
rip->p_stat = SRUN; // 親プロセスをrun状態に
} else { // mallocに成功。a2は物理アドレス
rpp->p_addr = a2;
while(n--)
copyseg(a1++, a2++); // データセグメントをコピー
}
u.u_procp = rip;
return(0);
}